package controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import model.RadioModel;
import model.RadioModelListener;


public class RadioController {
	
	private Properties properties = new Properties();
	
	private final String USERNAME = "Mick75";
	private final String PASSWORD = "317031";
	private final String LANGUAGE = "de";
	
	private final String LASTFM_SERVER_URL = "http://ws.audioscrobbler.com:80";
	
	private RadioModel model = null;
	private RadioPlayer player = null;
	
	
	public RadioController(RadioModel model) {
		
		this.model = model;
		
		player = new RadioPlayer(this.model);
		
		// Disable automatic redirects for all HTTP requests
	    HttpURLConnection.setFollowRedirects(false);
		
		final RadioModel fmodel = model;
		final RadioController fcontroller = this;
		
		this.model.addListener(new RadioModelListener() {
			public void emptyQueue() {
				System.out.println("RadioModelListener.emptyQueue");
				Playlist list;
				/*try {
					/list = fcontroller.getPlaylist();
					for (Track track : list.getTracks()) {
						fmodel.addTrack(track);
					}
					fmodel.printContent();
	
				} catch (IOException e) {
					e.printStackTrace();
				}*/
				
			}
		});
		player.addListener(new RadioPlayerListener() {
			
			public void durationUpdate(long nanoseconds) {
				System.out.println("RadioPlayerListener.durationUpdate");
			}
			
			public void endOfMedia() {
				System.out.println("RadioPlayerListener.endOfMedia");
				player.play();
				
			}
		});
		
		try {
			handshake();
			//adjust("lastfm://globaltags/Trance", "de");
			//player.play();
			
		
		} catch (IOException e) {
			e.printStackTrace();
		/*} catch (RadioException e) {
			e.printStackTrace();*/
		}
	}
	
	public void handshake() throws  IOException {
		
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("version", "1.3.1.1");
		parameterMap.put("platform", "unknown");
		parameterMap.put("username", USERNAME);
		
		String md5 = "";
        try {
        	md5 = CryptoTool.md5(PASSWORD);
        	
        } catch (NoSuchAlgorithmException e) {
        	System.out.println(e.getLocalizedMessage());
        	System.exit(1);
        }
        
        parameterMap.put("passwordmd5", md5);
        parameterMap.put("language", LANGUAGE);
    
		
		URL url = new URL(LASTFM_SERVER_URL + "/radio/handshake.php?" + createQuery(parameterMap, "UTF-8"));
        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
       
		httpConnection.setUseCaches(false);
		
        
        //getmethod.setQueryString(new NameValuePair[] {version, platform, username, passwordmd5, language});
       
        //client.executeMethod(getmethod);
      
	    InputStream is = httpConnection.getInputStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));

		String line = null;
		String[] pair = null;
		while ((line = reader.readLine()) != null) {
			System.out.println(line);
			pair = line.split("=");
			if ("session".equals(pair[0])) {
				properties.put("sessionkey", pair[1]);
			} else if ("base_url".equals(pair[0])) {
				properties.put("base_url", pair[1]);
			} else if ("base_path".equals(pair[0])) {
				properties.put("base_path", pair[1]);
			}
		}
	}
	
	/*public void adjust(String lastfmURI, String lang) throws RadioException, HttpException, IOException {
		
		client.getHostConfiguration().setHost((String) properties.get("base_url"), LASTFM_PORT, "http");
		
		getmethod = new GetMethod((String) properties.get("base_path") + "/adjust.php");
        
        NameValuePair session    = new NameValuePair("session", (String) properties.getProperty("sessionkey"));
        NameValuePair url   = new NameValuePair("url", lastfmURI);
        NameValuePair language   = new NameValuePair("lang", lang);
        
        getmethod.setQueryString(new NameValuePair[] {session, url, language});
        
        System.out.println(getmethod.getPath() + " " + getmethod.getQueryString());
        
        client.executeMethod(getmethod);
        
        InputStream is = getmethod.getResponseBodyAsStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        
        String line = null;
        String[] pair = null;
        while ((line = reader.readLine()) != null ) {
     	 
        	pair = line.split("=");
     	   if ("response".equals(pair[0])) {
     		   if (!"OK".equals(pair[1])) {
     			   throw new RadioException("could not adjust " + lastfmURI + " station");
     		   }
     	   } else if ("stationname".equals(pair[0])) {
     		   properties.put("stationname", new String(pair[1].getBytes("UTF-8"), "UTF-8"));    		
     	   } 
        }
	}
	
	public Playlist getPlaylist() throws HttpException, IOException {
		Playlist playlist = new Playlist();
                   
        client.getHostConfiguration().setHost((String) properties.get("base_url"), LASTFM_PORT, "http");
		
		getmethod = new GetMethod((String) properties.get("base_path") + "/xspf.php");
        
        NameValuePair session    = new NameValuePair("sk", (String) properties.getProperty("sessionkey"));
        NameValuePair discovery   = new NameValuePair("discovery", "0");
        NameValuePair desktop   = new NameValuePair("desktop", "1.5.3.4556");
        
        getmethod.setQueryString(new NameValuePair[] {session, discovery, desktop});
        client.executeMethod(getmethod);
        
        SAXParserFactory factory   = SAXParserFactory.newInstance();
       	factory.setValidating(true);
        factory.setNamespaceAware(true);
       System.out.println(getmethod.getResponseBodyAsString());
        SAXParser saxParser;
		try {
			saxParser = factory.newSAXParser();
			saxParser.parse(
					getmethod.getResponseBodyAsStream(), 
					new XSPFHandler(playlist));
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
        
		return playlist;
	}
	*/
	
	public void play() {
		
		player.play();
		
	}
	
	public void stop() {
		player.stop();
	}
	
	public void skip() {
		player.stop();
		player.play();
	}
	
	/**
     * Create a query string based on the given parameter map and the given charset encoding.
     * @param parameterMap The parameter map to be processed as query parameters.
     * @param charset The encoding to be applied.
     * @return The parameter map as query string.
     * @throws UnsupportedEncodingException If the given charset is not supported.
     */
    public static String createQuery(Map<String, String> parameterMap, String charset)
        throws UnsupportedEncodingException
    {
        StringBuilder query = new StringBuilder();

        for (Iterator<String> names = parameterMap.keySet().iterator(); names.hasNext();) {
            String name = names.next();
            String value = parameterMap.get(name);

            query.append("&");
            query.append(URLEncoder.encode(name, charset));
            query.append("=");
            query.append(URLEncoder.encode(value, charset));

        }

        return query.toString();
    }

	
}
